`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2023/08/31 13:29:22
// Design Name: 
// Module Name: e203_fpga
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module e203_fpga(
    input wire clk_in1_p,//clk_in1_p-AJ9
    input wire clk_in1_n,

    input wire ck_rst,//FPGA_RESET-J9
    // Dedicated QSPI interface
    // output wire qspi0_cs,
    // output wire qspi0_sck,
    // inout wire [3:0] qspi0_dq,

    //gpioA
    //inout wire [31:0] gpioA,//GPIOA00~GPIOA31   
    //  RX--->N8
    //  TX--->N9
    inout wire uart0_rx,
    inout wire uart0_tx,
    //  leds
    //  led0--->M9
    inout wire gpioA_0,

    //gpioB
    //inout wire [31:0] gpioB,//GPIOB00~GPIOB31 

    // JD (used for JTAG connection)
    //inout wire mcu_TDO,//MCU_TDO-G7
    output wire mcu_TDO,//MCU_TDO-G7
    inout wire mcu_TCK,//MCU_TCK-C2
    inout wire mcu_TDI,//MCU_TDI-D2
    inout wire mcu_TMS//MCU_TMS-H7
    //pmu_wakeup    
    // inout wire pmu_paden,  //PMU_VDDPADEN-U15
    // inout wire pmu_padrst, //PMU_VADDPARST_V15
    // inout wire mcu_wakeup  //MCU_WAKE-N15
    );
  
 
  // wire mcu_wakeup;  //MCU_WAKE-N15
  reg   [11:0]  clk32K_div_cnt;
  wire clk_out1;
  wire mmcm_locked;

  wire reset_periph;

  // wire ck_rst;

  // All wires connected to the chip top
  wire dut_clock;
  wire dut_reset;

  wire dut_io_pads_jtag_TCK_i_ival;
  wire dut_io_pads_jtag_TMS_i_ival;
  wire dut_io_pads_jtag_TMS_o_oval;
  wire dut_io_pads_jtag_TMS_o_oe;
  wire dut_io_pads_jtag_TMS_o_ie;
  wire dut_io_pads_jtag_TMS_o_pue;
  wire dut_io_pads_jtag_TMS_o_ds;
  wire dut_io_pads_jtag_TDI_i_ival;
  wire dut_io_pads_jtag_TDO_o_oval;
  wire dut_io_pads_jtag_TDO_o_oe;

  wire [32-1:0] dut_io_pads_gpioA_i_ival;
  wire [32-1:0] dut_io_pads_gpioA_o_oval;
  wire [32-1:0] dut_io_pads_gpioA_o_oe;

  wire [32-1:0] dut_io_pads_gpioB_i_ival;
  wire [32-1:0] dut_io_pads_gpioB_o_oval;
  wire [32-1:0] dut_io_pads_gpioB_o_oe;

  wire dut_io_pads_qspi0_sck_o_oval;
  wire dut_io_pads_qspi0_cs_0_o_oval;
  wire dut_io_pads_qspi0_dq_0_i_ival;
  wire dut_io_pads_qspi0_dq_0_o_oval;
  wire dut_io_pads_qspi0_dq_0_o_oe;
  wire dut_io_pads_qspi0_dq_1_i_ival;
  wire dut_io_pads_qspi0_dq_1_o_oval;
  wire dut_io_pads_qspi0_dq_1_o_oe;
  wire dut_io_pads_qspi0_dq_2_i_ival;
  wire dut_io_pads_qspi0_dq_2_o_oval;
  wire dut_io_pads_qspi0_dq_2_o_oe;
  wire dut_io_pads_qspi0_dq_3_i_ival;
  wire dut_io_pads_qspi0_dq_3_o_oval;
  wire dut_io_pads_qspi0_dq_3_o_oe;


  wire dut_io_pads_aon_erst_n_i_ival;
  wire dut_io_pads_aon_pmu_dwakeup_n_i_ival;
  wire dut_io_pads_aon_pmu_vddpaden_o_oval;
  wire dut_io_pads_aon_pmu_padrst_o_oval ;
  wire dut_io_pads_bootrom_n_i_ival;
  wire dut_io_pads_dbgmode0_n_i_ival;
  wire dut_io_pads_dbgmode1_n_i_ival;
  wire dut_io_pads_dbgmode2_n_i_ival;

  //=================================================
  // Clock & Reset
  wire clk_8388;
  wire clk_16M;
  reg  CLK32768KHZ;

  // assign ck_rst = fpga_rst & mcu_rst;


clk_wiz_1 u_clk_wiz_1 (
    .resetn     (ck_rst         ),
    .clk_in1_p  (clk_in1_p      ),
    .clk_in1_n  (clk_in1_n      ),
    
    .clk_out1   (clk_16M        ), // 16 MHz, this clock we set to 16MHz 
    .locked     (mmcm_locked    )
  );

always @(posedge clk_16M or negedge mmcm_locked) begin
    if(!mmcm_locked)
        clk32K_div_cnt <= 12'd0;
    else if (clk32K_div_cnt >= 12'd488)
        clk32K_div_cnt <= 12'd0;
    else
        clk32K_div_cnt <= clk32K_div_cnt + 1'b1;
end


always @(posedge clk_16M or negedge mmcm_locked) begin
    if(!mmcm_locked)
        CLK32768KHZ <= 1'd0;
    else if (clk32K_div_cnt == 12'd0 || clk32K_div_cnt == 12'd244 )
        CLK32768KHZ <= ~CLK32768KHZ ;
end

wire    CLK32768KHZ_BUF ;
BUFG u_BUFG(
    .O  (CLK32768KHZ_BUF),
    .I  (CLK32768KHZ    )
);

  

//   reset_sys ip_reset_sys
//   (
//     .slowest_sync_clk(clk_16M),
//     .ext_reset_in(ck_rst), // Active-low
//     .aux_reset_in(1'b1),
//     .mb_debug_sys_rst(1'b0),
//     .dcm_locked(mmcm_locked),
//     .mb_reset(),
//     .bus_struct_reset(),
//     .peripheral_reset(reset_periph),
//     .interconnect_aresetn(),
//     .peripheral_aresetn()
//   );

  //=================================================
  // SPI0 Interface

  wire [3:0] qspi0_ui_dq_o; 
  wire [3:0] qspi0_ui_dq_oe;
  wire [3:0] qspi0_ui_dq_i;

  PULLUP qspi0_pullup[3:0]
  (
    .O(qspi0_dq)
  );

  IOBUF qspi0_iobuf[3:0]
  (
    .IO(qspi0_dq),
    .O(qspi0_ui_dq_i),
    .I(qspi0_ui_dq_o),
    .T(~qspi0_ui_dq_oe)
  );


  //=================================================
  // IOBUF instantiation for GPIOs
  //-----------------GPIO for UART-------------------
  //      16--->UART0:RX               UART1:RX
  //      17--->UART0:TX               UART1:TX
  //      18--->UART2:RX
  //      19--->UART2:TX
  //UART0
  IOBUF #(.DRIVE (12), .IBUF_LOW_PWR("TRUE"),.IOSTANDARD ("DEFAULT"),.SLEW ("SLOW"))
  uart0_rx_iobuf
  (
    .O  (dut_io_pads_gpioA_i_ival[16]),   // Buffer output
    .IO (uart0_rx),                       // Buffer inout port (connect directly to top-level port)
    .I  (dut_io_pads_gpioA_o_oval[16]),   // Buffer input
    .T  (~dut_io_pads_gpioA_o_oe[16])     // 3-state enable input, high=input, low=output
  );
  IOBUF #(.DRIVE (12), .IBUF_LOW_PWR("TRUE"),.IOSTANDARD ("DEFAULT"),.SLEW ("SLOW"))
  uart0_tx_iobuf
  (
    .O  (dut_io_pads_gpioA_i_ival[17]),
    .IO (uart0_tx),
    .I  (dut_io_pads_gpioA_o_oval[17]),
    .T  (~dut_io_pads_gpioA_o_oe[17])
  );
  //LED0
  IOBUF #(.DRIVE (12), .IBUF_LOW_PWR("TRUE"),.IOSTANDARD ("DEFAULT"),.SLEW ("SLOW"))
  gpioA_0_iobuf
  (
    .O  (dut_io_pads_gpioA_i_ival[0]),
    .IO (gpioA_0),
    .I  (dut_io_pads_gpioA_o_oval[0]),
    .T  (~dut_io_pads_gpioA_o_oe[0])
  );
  // IOBUF
  // #(
  //   .DRIVE(12),
  //   .IBUF_LOW_PWR("TRUE"),
  //   .IOSTANDARD("DEFAULT"),
  //   .SLEW("SLOW")
  // )
  // gpioA_iobuf[31:0]
  // (
  //   .O(dut_io_pads_gpioA_i_ival),
  //   .IO(gpioA),
  //   .I(dut_io_pads_gpioA_o_oval),
  //   .T(~dut_io_pads_gpioA_o_oe)
  // );
/*
  IOBUF
  #(
    .DRIVE(12),
    .IBUF_LOW_PWR("TRUE"),
    .IOSTANDARD("DEFAULT"),
    .SLEW("SLOW")
  )
  gpioB_iobuf[31:0]
  (
    .O(dut_io_pads_gpioB_i_ival),
    .IO(gpioB),
    .I(dut_io_pads_gpioB_o_oval),
    .T(~dut_io_pads_gpioB_o_oe)
  );
  */
  //=================================================
  // JTAG IOBUFs

  wire iobuf_jtag_TCK_o;
  IOBUF
  #(
    .DRIVE(12),
    .IBUF_LOW_PWR("TRUE"),
    .IOSTANDARD("DEFAULT"),
    .SLEW("SLOW")
  )
  IOBUF_jtag_TCK
  (
    .O(iobuf_jtag_TCK_o),
    .IO(mcu_TCK),
    .I(1'b0),
    .T(1'b1)
  );
  
  assign dut_io_pads_jtag_TCK_i_ival = iobuf_jtag_TCK_o ;
  PULLUP pullup_TCK (.O(mcu_TCK));

  wire iobuf_jtag_TMS_o;
  IOBUF
  #(
    .DRIVE(12),
    .IBUF_LOW_PWR("TRUE"),
    .IOSTANDARD("DEFAULT"),
    .SLEW("SLOW")
  )
  IOBUF_jtag_TMS
  (
    .O(iobuf_jtag_TMS_o),
    .IO(mcu_TMS),
    .I(1'b0),
    .T(1'b1)
  );
  assign dut_io_pads_jtag_TMS_i_ival = iobuf_jtag_TMS_o;
  PULLUP pullup_TMS (.O(mcu_TMS));

  wire iobuf_jtag_TDI_o;
  IOBUF
  #(
    .DRIVE(12),
    .IBUF_LOW_PWR("TRUE"),
    .IOSTANDARD("DEFAULT"),
    .SLEW("SLOW")
  )
  IOBUF_jtag_TDI
  (
    .O(iobuf_jtag_TDI_o),
    .IO(mcu_TDI),
    .I(1'b0),
    .T(1'b1)
  );
  assign dut_io_pads_jtag_TDI_i_ival = iobuf_jtag_TDI_o;
  PULLUP pullup_TDI (.O(mcu_TDI));

  // wire iobuf_jtag_TDO_o;
  // IOBUF
  // #(
  //   .DRIVE(12),
  //   .IBUF_LOW_PWR("TRUE"),
  //   .IOSTANDARD("DEFAULT"),
  //   .SLEW("SLOW")
  // )
  // IOBUF_jtag_TDO
  // (
  //   .O(iobuf_jtag_TDO_o),
  //   .IO(mcu_TDO),
  //   .I(dut_io_pads_jtag_TDO_o_oval),
  //   .T(~dut_io_pads_jtag_TDO_o_oe)
  // );
  assign mcu_TDO = dut_io_pads_jtag_TDO_o_oval;
  //wire iobuf_jtag_TRST_n_o;
  //IOBUF
  //#(
  //  .DRIVE(12),
  //  .IBUF_LOW_PWR("TRUE"),
  //  .IOSTANDARD("DEFAULT"),
  //  .SLEW("SLOW")
  //)

  //=================================================
  // Assignment of IOBUF "IO" pins to package pins

  // Pins IO0-IO13
  // Shield header row 0: PD0-PD7

  // Use the LEDs for some more useful debugging things.
  // assign pmu_paden  = dut_io_pads_aon_pmu_vddpaden_o_oval;  
  // assign pmu_padrst = dut_io_pads_aon_pmu_padrst_o_oval;		

  // model select
  assign dut_io_pads_bootrom_n_i_ival  = 1'b0;   //
  assign dut_io_pads_dbgmode0_n_i_ival = 1'b1;
  assign dut_io_pads_dbgmode1_n_i_ival = 1'b1;
  assign dut_io_pads_dbgmode2_n_i_ival = 1'b1;

  e203_soc_top dut
  (
    .hfextclk(clk_16M),
    .hfxoscen(),

    .lfextclk(CLK32768KHZ_BUF), 
    .lfxoscen(),

       // Note: this is the real SoC top AON domain slow clock
    .io_pads_jtag_TCK_i_ival(dut_io_pads_jtag_TCK_i_ival),
    .io_pads_jtag_TMS_i_ival(dut_io_pads_jtag_TMS_i_ival),
    .io_pads_jtag_TDI_i_ival(dut_io_pads_jtag_TDI_i_ival),
    .io_pads_jtag_TDO_o_oval(dut_io_pads_jtag_TDO_o_oval),
    .io_pads_jtag_TDO_o_oe  (dut_io_pads_jtag_TDO_o_oe),

    .io_pads_gpioA_i_ival(dut_io_pads_gpioA_i_ival),
    .io_pads_gpioA_o_oval(dut_io_pads_gpioA_o_oval),
    .io_pads_gpioA_o_oe  (dut_io_pads_gpioA_o_oe),

    .io_pads_gpioB_i_ival(dut_io_pads_gpioB_i_ival),
    .io_pads_gpioB_o_oval(dut_io_pads_gpioB_o_oval),
    .io_pads_gpioB_o_oe  (dut_io_pads_gpioB_o_oe),

    //QPSI
    .io_pads_qspi0_sck_o_oval (),
    .io_pads_qspi0_cs_0_o_oval(),
    .io_pads_qspi0_dq_0_i_ival(),
    .io_pads_qspi0_dq_0_o_oval(),
    .io_pads_qspi0_dq_0_o_oe  (),
    .io_pads_qspi0_dq_1_i_ival(),
    .io_pads_qspi0_dq_1_o_oval(),
    .io_pads_qspi0_dq_1_o_oe  (),
    .io_pads_qspi0_dq_2_i_ival(),
    .io_pads_qspi0_dq_2_o_oval(),
    .io_pads_qspi0_dq_2_o_oe  (),
    .io_pads_qspi0_dq_3_i_ival(),
    .io_pads_qspi0_dq_3_o_oval(),
    .io_pads_qspi0_dq_3_o_oe  (),


    // Note: this is the real SoC top level reset signal
    .io_pads_aon_erst_n_i_ival(ck_rst),

    //PMU
    .io_pads_aon_pmu_dwakeup_n_i_ival(),
    .io_pads_aon_pmu_vddpaden_o_oval(),
    .io_pads_aon_pmu_padrst_o_oval    ( ),

    .io_pads_bootrom_n_i_ival       (dut_io_pads_bootrom_n_i_ival),
    .io_pads_dbgmode0_n_i_ival       (dut_io_pads_dbgmode0_n_i_ival),
    .io_pads_dbgmode1_n_i_ival       (dut_io_pads_dbgmode1_n_i_ival),
    .io_pads_dbgmode2_n_i_ival       (dut_io_pads_dbgmode2_n_i_ival) 
  );

  // Assign reasonable values to otherwise unconnected inputs to chip top
  // wire iobuf_dwakeup_o;
  // IOBUF
  // #(
  //   .DRIVE(12),
  //   .IBUF_LOW_PWR("TRUE"),
  //   .IOSTANDARD("DEFAULT"),
  //   .SLEW("SLOW")
  // )
  // IOBUF_dwakeup_n
  // (
  //   .O(iobuf_dwakeup_o),
  //   .IO(mcu_wakeup),
  //   .I(1'b1),
  //   .T(1'b1)
  // );
  //assign dut_io_pads_aon_pmu_dwakeup_n_i_ival = (~iobuf_dwakeup_o);

  

  // assign dut_io_pads_aon_pmu_vddpaden_i_ival = 1'b1;

  // assign qspi0_sck = dut_io_pads_qspi0_sck_o_oval;
  // assign qspi0_cs  = dut_io_pads_qspi0_cs_0_o_oval;
  // assign qspi0_ui_dq_o = {
  //   dut_io_pads_qspi0_dq_3_o_oval,
  //   dut_io_pads_qspi0_dq_2_o_oval,
  //   dut_io_pads_qspi0_dq_1_o_oval,
  //   dut_io_pads_qspi0_dq_0_o_oval
  // };
  // assign qspi0_ui_dq_oe = {
  //   dut_io_pads_qspi0_dq_3_o_oe,
  //   dut_io_pads_qspi0_dq_2_o_oe,
  //   dut_io_pads_qspi0_dq_1_o_oe,
  //   dut_io_pads_qspi0_dq_0_o_oe
  // };
  // assign dut_io_pads_qspi0_dq_0_i_ival = qspi0_ui_dq_i[0];
  // assign dut_io_pads_qspi0_dq_1_i_ival = qspi0_ui_dq_i[1];
  // assign dut_io_pads_qspi0_dq_2_i_ival = qspi0_ui_dq_i[2];
  // assign dut_io_pads_qspi0_dq_3_i_ival = qspi0_ui_dq_i[3];

design_1_wrapper u_design_1_wrapper
   (
);
endmodule
